package stage1.test;

import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.*;

public class Task {
    public static void main(String args[]) {
        task1();
        task2();
        task3();
        task4();
        task5();
    }

    /**
     * 1. 编程题 提示用户输入年月日信息，判断这一天是这一年中的第几天并打印。
     */
    public static void task1() {
        System.out.println("请输入日期（例如2008-02-10）:");
        Scanner sc = new Scanner(System.in);
        String date = sc.nextLine();
        try {
            System.out.println("日期" + date + "是一年中的第" + getDays(date) + "天");
        } catch (Exception e) {
            System.out.println("日期格式错误！");
        }
    }

    /**
     * 获取天数
     *
     * @param date
     * @return
     */
    private static int getDays(String date) {
        int year = Integer.parseInt(date.substring(0, 4));
        int month = Integer.parseInt(date.substring(5, 7));
        int day = Integer.parseInt(date.substring(8, 10));
        LocalDate lDate = LocalDate.of(year, month, day);
        if (month == 1) {
            return day;
        }
        int[] arr = new int[]{31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
        if (lDate.isLeapYear()) {
            return arr[month - 2] + day;
        }

        return arr[month - 2] + day - 1;
    }

    /**
     * 2. 编程题 编程找出 1000 以内的所有完数并打印出来。 所谓完数就是一个数恰好等于它的因子之和，如：6=1＋2＋3
     */
    public static void task2() {
        for (int i = 1; i < 1001; i++) {
            int sum = 0;
            for (int j = 1; j < i; j++) {
                if (i % j == 0) {
                    sum += j;
                }
            }
            if (i == sum) {
                System.out.println(i);
            }
        }
    }

    /**
     * 3. 编程题 实现双色球抽奖游戏中奖号码的生成，中奖号码由 6 个红球号码和 1 个蓝球号码组成。
     * 其中红球号码要求随机生成 6 个 1~33 之间不重复的随机号码。 其中蓝球号码要求随机生成 1 个 1~16 之间的随机号码。
     */
    public static void task3() {
        Random r = new Random();
        int blueBallNumber = r.nextInt(15) + 1;
        String redBallNumber = getRedBall(new ArrayList<>());
        System.out.println("双色球抽奖游戏中奖号码已生成。蓝球号码是：" + blueBallNumber + "，红球号码是" + redBallNumber);
    }

    /**
     * 获取红球号码
     *
     * @param redList
     * @return
     */
    private static String getRedBall(List<Integer> redList) {
        Random r = new Random();
        int red = r.nextInt(32) + 1;
        if (redList.size() < 6) {
            if (!redList.contains(red)) {
                redList.add(red);
            }
            getRedBall(redList);
        }
        String redBallNumber = "";
        for (Integer redBall : redList) {
            redBallNumber += redBall + ",";
        }

        return redBallNumber.substring(0, redBallNumber.length() - 1);
    }

    /**
     * 4. 编程题 自定义数组扩容规则，当已存储元素数量达到总容量的 80%时，扩容 1.5 倍。
     * 例如，总容量是 10，当输入第 8 个元素时，数组进行扩容，容量从 10 变 15。
     */
    public static void task4() {
        // 创建要测试的数组。本来想做成想php那种部分数组类型的。后面查了下发下好像java数组必须限定类型
        int[] oldArray = new int[7];
        oldArray[0] = 1;
        oldArray[1] = 3;
        oldArray[2] = 2;
        oldArray[3] = 8;
        oldArray[4] = 2;
        oldArray[5] = 8;
        System.out.println("oldArray数组长度：" + oldArray.length);
        // 获取要扩容的长度
        int increasedLength = getIncreasedLength(oldArray);
        if (increasedLength > 0) {
            // 扩容
            int newArrayLenth = oldArray.length + increasedLength;
            int[] newArray = new int[newArrayLenth];
            System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
            oldArray = newArray;
            System.out.println("以达到扩容条件，扩容后数组长度：" + oldArray.length);
        } else {
            System.out.println("不需要扩容！");
        }
    }

    // 获取要扩容的长度
    private static int getIncreasedLength(int[] arr) {
        int len = arr.length;
        int capacity = 0;
        try {
            for (int i = 0; i < arr.length; i++
            ) {
                if (0 != arr[i]) {
                    capacity = i + 1;
                }
            }
        } catch (Exception e) {
        }
        double usedIncreased = (double) capacity / len;
        DecimalFormat df = new DecimalFormat("0.00%");
        String usedIncreasedString = df.format(usedIncreased);
        System.out.println("oldArray数组已使用容量：" + usedIncreasedString);
        if (usedIncreased > 0.8) {
            len = (int) ((double) len * 0.5);
            if (arr.length % 2 == 1) {
                len = len + 1;
            }
        } else {
            len = 0;
        }

        return len;
    }

    /**
     * 5. 编程题 使用二维数组和循环实现五子棋游戏棋盘的绘制，具体如下：
     */
    public static void task5() {
        int[][] backgammonBoard = new int[17][16];
        int row = 0;
        for (int[] i : backgammonBoard) {
            int column = 0;
            // 第0行输出空格
            if (row == 0) {
                row++;
                System.out.print("   ");
            } else {
                System.out.print(getPiece((row++) - 1) + "  ");
            }

            for (int j : i) {
                // 第0行输出键盘布局，因为上面处理的时候已经加1这块判断等于1即可
                if (row == 1) {
                    System.out.print(getPiece(column++) + "  ");
                } else {
                    column++;
                    System.out.print("+  ");
                }

            }
            System.out.println();
        }
    }

    public static String getPiece(int column) {
        if (column < 10) {
            return String.valueOf(column);
        }
        switch (column) {
            case 10:
                return "a";
            case 11:
                return "b";
            case 12:
                return "c";
            case 13:
                return "d";
            case 14:
                return "e";
            case 15:
                return "f";
            default:
                return "";
        }
    }
}
